using System;
using System.Collections.Generic;
using System.Text;

namespace GameLib.Utils
{
    public struct GameVector : IEquatable<GameVector>
    {
        public int X;
        public int Y;

        public GameVector(int x, int y)
        {
            X = x;
            Y = y;
        }

        public GameVector(int value)
        {
            X = Y = value;
        }

        // Summary:
        //     Returns a vector pointing in the opposite direction.
        //
        // Parameters:
        //   value:
        //     Source vector.
        //
        // Returns:
        //     Vector pointing in the opposite direction.
        public static GameVector operator -(GameVector value)
        {
            return new GameVector(-value.X, -value.Y);
        }
        //
        // Summary:
        //     Subtracts a vector from a vector.
        //
        // Parameters:
        //   value1:
        //     Source vector.
        //
        //   value2:
        //     source vector.
        //
        // Returns:
        //     Result of the subtraction.
        public static GameVector operator -(GameVector value1, GameVector value2)
        {
            return new GameVector(value1.X - value2.X, value1.Y - value2.Y);
        }
        //
        // Summary:
        //     Tests vectors for inequality.
        //
        // Parameters:
        //   value1:
        //     Vector to compare.
        //
        //   value2:
        //     Vector to compare.
        //
        // Returns:
        //     Returns true if the vectors are not equal, false otherwise.
        public static bool operator !=(GameVector value1, GameVector value2)
        {
            return value1.X != value2.X || value1.Y != value2.Y;
        }
        //
        // Summary:
        //     Multiplies a vector by a scalar value.
        //
        // Parameters:
        //   scaleFactor:
        //     Scalar value.
        //
        //   value:
        //     Source vector.
        //
        // Returns:
        //     Result of the multiplication.
        public static GameVector operator *(float scaleFactor, GameVector value)
        {
            return new GameVector((int)Math.Round(value.X * scaleFactor), (int)Math.Round(value.Y * scaleFactor));
        }

        public static GameVector operator *(int scaleFactor, GameVector value)
        {
            return new GameVector(value.X * scaleFactor, value.Y * scaleFactor);
        }
        //
        // Summary:
        //     Multiplies a vector by a scalar value.
        //
        // Parameters:
        //   value:
        //     Source vector.
        //
        //   scaleFactor:
        //     Scalar value.
        //
        // Returns:
        //     Result of the multiplication.
        public static GameVector operator *(GameVector value, float scaleFactor)
        {
            return new GameVector((int)Math.Round(value.X * scaleFactor), (int)Math.Round(value.Y * scaleFactor));
        }
        public static GameVector operator *(GameVector value, int scaleFactor)
        {
            return new GameVector(value.X * scaleFactor, value.Y * scaleFactor);
        }

        //
        // Summary:
        //     Divides a vector by a scalar value.
        //
        // Parameters:
        //   value1:
        //     Source vector.
        //
        //   divider:
        //     The divisor.
        //
        // Returns:
        //     The source vector divided by b.
        public static GameVector operator /(GameVector value1, int divider)
        {
            return new GameVector(value1.X / divider, value1.Y / divider);
        }

        //
        // Summary:
        //     Adds two vectors.
        //
        // Parameters:
        //   value1:
        //     Source vector.
        //
        //   value2:
        //     Source vector.
        //
        // Returns:
        //     Sum of the source vectors.
        public static GameVector operator +(GameVector value1, GameVector value2)
        {
            return new GameVector(value1.X + value2.X, value1.Y + value2.Y);
        }
        //
        // Summary:
        //     Tests vectors for equality.
        //
        // Parameters:
        //   value1:
        //     Source vector.
        //
        //   value2:
        //     Source vector.
        //
        // Returns:
        //     true if the vectors are equal; false otherwise.
        public static bool operator ==(GameVector value1, GameVector value2)
        {
            return value1.X == value2.X && value1.Y == value2.Y;
        }

        public static GameVector operator *(GameVector value1, GameVector value2)
        {
            return new GameVector(value1.X * value2.X, value1.Y * value2.Y);
        }

        public override int GetHashCode()
        {
            return X ^ Y;
        }

        public override string ToString()
        {
            return string.Format("({0}, {1})", X, Y);
        }

        
        public override bool Equals(object obj)
        {
            if (obj is GameVector)
                return this == (GameVector)obj;
            else
                return false;
        }

        #region IEquatable<Vector2Int> Members

        public bool Equals(GameVector other)
        {
            return this == other;
        }

        #endregion

        public static float Distance(GameVector vector1, GameVector vector2)
        {
            return (float)Math.Sqrt((vector1.X - vector2.X) * (vector1.X - vector2.X) + (vector1.Y - vector2.Y) * (vector1.Y - vector2.Y));
        }

		public static readonly GameVector Zero = new GameVector(0); 
    }
}
